1   /*                        __    __  __  __    __  ___
2    *                       \  \  /  /    \  \  /  /  __/
3    *                        \  \/  /  /\  \  \/  /  /
4    *                         \____/__/  \__\____/__/.ɪᴏ
5    * ᶜᵒᵖʸʳᶦᵍʰᵗ ᵇʸ ᵛᵃᵛʳ ⁻ ˡᶦᶜᵉⁿˢᵉᵈ ᵘⁿᵈᵉʳ ᵗʰᵉ ᵃᵖᵃᶜʰᵉ ˡᶦᶜᵉⁿˢᵉ ᵛᵉʳˢᶦᵒⁿ ᵗʷᵒ ᵈᵒᵗ ᶻᵉʳᵒ
6    */
7   package io.vavr.collection;
8   
9   import io.vavr.*;
10  import io.vavr.control.Option;
11  import io.vavr.collection.List.Nil;
12  import io.vavr.collection.ListModule.Combinations;
13  import io.vavr.collection.ListModule.SplitAt;
14  
15  import java.io.*;
16  import java.util.*;
17  import java.util.function.*;
18  import java.util.stream.Collector;
19  
20  import static io.vavr.collection.JavaConverters.ChangePolicy.IMMUTABLE;
21  import static io.vavr.collection.JavaConverters.ChangePolicy.MUTABLE;
22  
23  /**
24   * An immutable {@code List} is an eager sequence of elements. Its immutability makes it suitable for concurrent programming.
25   * <p>
26   * A {@code List} is composed of a {@code head} element and a {@code tail} {@code List}.
27   * <p>
28   * There are two implementations of the {@code List} interface:
29   *
30   * <ul>
31   * <li>{@link Nil}, which represents the empty {@code List}.</li>
32   * <li>{@link Cons}, which represents a {@code List} containing one or more elements.</li>
33   * </ul>
34   *
35   * A {@code List} is a {@code Stack} in the sense that it stores elements allowing a last-in-first-out (LIFO) retrieval.
36   * <p>
37   * Stack API:
38   *
39   * <ul>
40   * <li>{@link #peek()}</li>
41   * <li>{@link #peekOption()}</li>
42   * <li>{@link #pop()}</li>
43   * <li>{@link #popOption()}</li>
44   * <li>{@link #pop2()}</li>
45   * <li>{@link #pop2Option()}</li>
46   * <li>{@link #push(Object)}</li>
47   * <li>{@link #push(Object[])}</li>
48   * <li>{@link #pushAll(Iterable)}</li>
49   * </ul>
50   *
51   * Methods to obtain a {@code List}:
52   *
53   * <pre>
54   * <code>
55   * // factory methods
56   * List.empty()                        // = List.of() = Nil.instance()
57   * List.of(x)                          // = new Cons&lt;&gt;(x, Nil.instance())
58   * List.of(Object...)                  // e.g. List.of(1, 2, 3)
59   * List.ofAll(Iterable)                // e.g. List.ofAll(Stream.of(1, 2, 3)) = 1, 2, 3
60   * List.ofAll(&lt;primitive array&gt;) // e.g. List.of(new int[] {1, 2, 3}) = 1, 2, 3
61   *
62   * // int sequences
63   * List.range(0, 3)              // = 0, 1, 2
64   * List.rangeClosed(0, 3)        // = 0, 1, 2, 3
65   * </code>
66   * </pre>
67   *
68   * Note: A {@code List} is primarily a {@code Seq} and extends {@code Stack} for technical reasons (so {@code Stack} does not need to wrap {@code List}).
69   * <p>
70   * If operating on a {@code List}, please prefer
71   *
72   * <ul>
73   * <li>{@link #prepend(Object)} over {@link #push(Object)}</li>
74   * <li>{@link #prependAll(Iterable)} over {@link #pushAll(Iterable)}</li>
75   * <li>{@link #tail()} over {@link #pop()}</li>
76   * <li>{@link #tailOption()} over {@link #popOption()}</li>
77   * </ul>
78   *
79   * Factory method applications:
80   *
81   * <pre>
82   * <code>
83   * List&lt;Integer&gt;       s1 = List.of(1);
84   * List&lt;Integer&gt;       s2 = List.of(1, 2, 3);
85   *                           // = List.of(new Integer[] {1, 2, 3});
86   *
87   * List&lt;int[]&gt;         s3 = List.ofAll(1, 2, 3);
88   * List&lt;List&lt;Integer&gt;&gt; s4 = List.ofAll(List.of(1, 2, 3));
89   *
90   * List&lt;Integer&gt;       s5 = List.ofAll(1, 2, 3);
91   * List&lt;Integer&gt;       s6 = List.ofAll(List.of(1, 2, 3));
92   *
93   * // cuckoo's egg
94   * List&lt;Integer[]&gt;     s7 = List.&lt;Integer[]&gt; of(new Integer[] {1, 2, 3});
95   * </code>
96   * </pre>
97   *
98   * Example: Converting a String to digits
99   *
100  * <pre>
101  * <code>
102  * // = List(1, 2, 3)
103  * List.of("123".toCharArray()).map(c -&gt; Character.digit(c, 10))
104  * </code>
105  * </pre>
106  *
107  * See Okasaki, Chris: <em>Purely Functional Data Structures</em> (p. 7 ff.). Cambridge, 2003.
108  *
109  * @param <T> Component type of the List
110  * @author Daniel Dietrich
111  */
112 public interface List<T> extends LinearSeq<T> {
113 
114     long serialVersionUID = 1L;
115 
116     /**
117      * Returns a {@link java.util.stream.Collector} which may be used in conjunction with
118      * {@link java.util.stream.Stream#collect(java.util.stream.Collector)} to obtain a {@link List}.
119      *
120      * @param <T> Component type of the List.
121      * @return A io.vavr.collection.List Collector.
122      */
123     static <T> Collector<T, ArrayList<T>, List<T>> collector() {
124         final Supplier<ArrayList<T>> supplier = ArrayList::new;
125         final BiConsumer<ArrayList<T>, T> accumulator = ArrayList::add;
126         final BinaryOperator<ArrayList<T>> combiner = (left, right) -> {
127             left.addAll(right);
128             return left;
129         };
130         final Function<ArrayList<T>, List<T>> finisher = List::ofAll;
131         return Collector.of(supplier, accumulator, combiner, finisher);
132     }
133 
134     /**
135      * Returns the single instance of Nil. Convenience method for {@code Nil.instance()} .
136      * <p>
137      * Note: this method intentionally returns type {@code List} and not {@code Nil}. This comes handy when folding.
138      * If you explicitly need type {@code Nil} use {@linkplain Nil#instance()}.
139      *
140      * @param <T> Component type of Nil, determined by type inference in the particular context.
141      * @return The empty list.
142      */
143     static <T> List<T> empty() {
144         return Nil.instance();
145     }
146 
147     /**
148      * A {@code List} is computed synchronously.
149      *
150      * @return false
151      */
152     @Override
153     default boolean isAsync() {
154         return false;
155     }
156 
157     @Override
158     boolean isEmpty();
159 
160     /**
161      * A {@code List} is computed eagerly.
162      *
163      * @return false
164      */
165     @Override
166     default boolean isLazy() {
167         return false;
168     }
169 
170     /**
171      * Narrows a widened {@code List<? extends T>} to {@code List<T>}
172      * by performing a type-safe cast. This is eligible because immutable/read-only
173      * collections are covariant.
174      *
175      * @param list A {@code List}.
176      * @param <T>  Component type of the {@code List}.
177      * @return the given {@code list} instance as narrowed type {@code List<T>}.
178      */
179     @SuppressWarnings("unchecked")
180     static <T> List<T> narrow(List<? extends T> list) {
181         return (List<T>) list;
182     }
183 
184     /**
185      * Returns a singleton {@code List}, i.e. a {@code List} of one element.
186      *
187      * @param element An element.
188      * @param <T>     The component type
189      * @return A new List instance containing the given element
190      */
191     static <T> List<T> of(T element) {
192         return new Cons<>(element, Nil.instance());
193     }
194 
195     /**
196      * Creates a List of the given elements.
197      * <pre>
198      * <code>
199      *   List.of(1, 2, 3, 4)
200      * = Nil.instance().prepend(4).prepend(3).prepend(2).prepend(1)
201      * = new Cons(1, new Cons(2, new Cons(3, new Cons(4, Nil.instance()))))
202      * </code>
203      * </pre>
204      *
205      * @param <T>      Component type of the List.
206      * @param elements Zero or more elements.
207      * @return A list containing the given elements in the same order.
208      * @throws NullPointerException if {@code elements} is null
209      */
210     @SafeVarargs
211     static <T> List<T> of(T... elements) {
212         Objects.requireNonNull(elements, "elements is null");
213         List<T> result = Nil.instance();
214         for (int i = elements.length - 1; i >= 0; i--) {
215             result = result.prepend(elements[i]);
216         }
217         return result;
218     }
219 
220     /**
221      * Creates a List of the given elements.
222      * <p>
223      * The resulting list has the same iteration order as the given iterable of elements
224      * if the iteration order of the elements is stable.
225      *
226      * @param <T>      Component type of the List.
227      * @param elements An Iterable of elements.
228      * @return A list containing the given elements in the same order.
229      * @throws NullPointerException if {@code elements} is null
230      */
231     @SuppressWarnings("unchecked")
232     static <T> List<T> ofAll(Iterable<? extends T> elements) {
233         Objects.requireNonNull(elements, "elements is null");
234         if (elements instanceof List) {
235             return (List<T>) elements;
236         } else if (elements instanceof java.util.List) {
237             List<T> result = Nil.instance();
238             final java.util.List<T> list = (java.util.List<T>) elements;
239             final ListIterator<T> iterator = list.listIterator(list.size());
240             while (iterator.hasPrevious()) {
241                 result = result.prepend(iterator.previous());
242             }
243             return result;
244         } else if (elements instanceof NavigableSet) {
245             List<T> result = Nil.instance();
246             final java.util.Iterator<T> iterator = ((NavigableSet<T>) elements).descendingIterator();
247             while (iterator.hasNext()) {
248                 result = result.prepend(iterator.next());
249             }
250             return result;
251         } else {
252             List<T> result = Nil.instance();
253             for (T element : elements) {
254                 result = result.prepend(element);
255             }
256             return result.reverse();
257         }
258     }
259 
260     /**
261      * Creates a List that contains the elements of the given {@link java.util.stream.Stream}.
262      *
263      * @param javaStream A {@link java.util.stream.Stream}
264      * @param <T>        Component type of the Stream.
265      * @return A List containing the given elements in the same order.
266      */
267     static <T> List<T> ofAll(java.util.stream.Stream<? extends T> javaStream) {
268         Objects.requireNonNull(javaStream, "javaStream is null");
269         final java.util.Iterator<? extends T> iterator = javaStream.iterator();
270         List<T> list = List.empty();
271         while (iterator.hasNext()) {
272             list = list.prepend(iterator.next());
273         }
274         return list.reverse();
275     }
276 
277     /**
278      * Creates a List from boolean values.
279      *
280      * @param elements boolean values
281      * @return A new List of Boolean values
282      * @throws NullPointerException if elements is null
283      */
284     static List<Boolean> ofAll(boolean... elements) {
285         Objects.requireNonNull(elements, "elements is null");
286         return ofAll(Iterator.ofAll(elements));
287     }
288 
289     /**
290      * Creates a List from byte values.
291      *
292      * @param elements byte values
293      * @return A new List of Byte values
294      * @throws NullPointerException if elements is null
295      */
296     static List<Byte> ofAll(byte... elements) {
297         Objects.requireNonNull(elements, "elements is null");
298         return ofAll(Iterator.ofAll(elements));
299     }
300 
301     /**
302      * Creates a List from char values.
303      *
304      * @param elements char values
305      * @return A new List of Character values
306      * @throws NullPointerException if elements is null
307      */
308     static List<Character> ofAll(char... elements) {
309         Objects.requireNonNull(elements, "elements is null");
310         return ofAll(Iterator.ofAll(elements));
311     }
312 
313     /**
314      * Creates a List from double values.
315      *
316      * @param elements double values
317      * @return A new List of Double values
318      * @throws NullPointerException if elements is null
319      */
320     static List<Double> ofAll(double... elements) {
321         Objects.requireNonNull(elements, "elements is null");
322         return ofAll(Iterator.ofAll(elements));
323     }
324 
325     /**
326      * Creates a List from float values.
327      *
328      * @param elements a float values
329      * @return A new List of Float values
330      * @throws NullPointerException if elements is null
331      */
332     static List<Float> ofAll(float... elements) {
333         Objects.requireNonNull(elements, "elements is null");
334         return ofAll(Iterator.ofAll(elements));
335     }
336 
337     /**
338      * Creates a List from int values.
339      *
340      * @param elements int values
341      * @return A new List of Integer values
342      * @throws NullPointerException if elements is null
343      */
344     static List<Integer> ofAll(int... elements) {
345         Objects.requireNonNull(elements, "elements is null");
346         return ofAll(Iterator.ofAll(elements));
347     }
348 
349     /**
350      * Creates a List from long values.
351      *
352      * @param elements long values
353      * @return A new List of Long values
354      * @throws NullPointerException if elements is null
355      */
356     static List<Long> ofAll(long... elements) {
357         Objects.requireNonNull(elements, "elements is null");
358         return ofAll(Iterator.ofAll(elements));
359     }
360 
361     /**
362      * Creates a List from short values.
363      *
364      * @param elements short values
365      * @return A new List of Short values
366      * @throws NullPointerException if elements is null
367      */
368     static List<Short> ofAll(short... elements) {
369         Objects.requireNonNull(elements, "elements is null");
370         return ofAll(Iterator.ofAll(elements));
371     }
372 
373     /**
374      * Returns a List containing {@code n} values of a given Function {@code f}
375      * over a range of integer values from 0 to {@code n - 1}.
376      *
377      * @param <T> Component type of the List
378      * @param n   The number of elements in the List
379      * @param f   The Function computing element values
380      * @return A List consisting of elements {@code f(0),f(1), ..., f(n - 1)}
381      * @throws NullPointerException if {@code f} is null
382      */
383     static <T> List<T> tabulate(int n, Function<? super Integer, ? extends T> f) {
384         Objects.requireNonNull(f, "f is null");
385         return Collections.tabulate(n, f, empty(), List::of);
386     }
387 
388     /**
389      * Returns a List containing {@code n} values supplied by a given Supplier {@code s}.
390      *
391      * @param <T> Component type of the List
392      * @param n   The number of elements in the List
393      * @param s   The Supplier computing element values
394      * @return A List of size {@code n}, where each element contains the result supplied by {@code s}.
395      * @throws NullPointerException if {@code s} is null
396      */
397     static <T> List<T> fill(int n, Supplier<? extends T> s) {
398         Objects.requireNonNull(s, "s is null");
399         return Collections.fill(n, s, empty(), List::of);
400     }
401 
402     static List<Character> range(char from, char toExclusive) {
403         return ofAll(Iterator.range(from, toExclusive));
404     }
405 
406     static List<Character> rangeBy(char from, char toExclusive, int step) {
407         return ofAll(Iterator.rangeBy(from, toExclusive, step));
408     }
409 
410     @GwtIncompatible
411     static List<Double> rangeBy(double from, double toExclusive, double step) {
412         return ofAll(Iterator.rangeBy(from, toExclusive, step));
413     }
414 
415     /**
416      * Creates a List of int numbers starting from {@code from}, extending to {@code toExclusive - 1}.
417      * <p>
418      * Examples:
419      * <pre>
420      * <code>
421      * List.range(0, 0)  // = List()
422      * List.range(2, 0)  // = List()
423      * List.range(-2, 2) // = List(-2, -1, 0, 1)
424      * </code>
425      * </pre>
426      *
427      * @param from        the first number
428      * @param toExclusive the last number + 1
429      * @return a range of int values as specified or the empty range if {@code from >= toExclusive}
430      */
431     static List<Integer> range(int from, int toExclusive) {
432         return ofAll(Iterator.range(from, toExclusive));
433     }
434 
435     /**
436      * Creates a List of int numbers starting from {@code from}, extending to {@code toExclusive - 1},
437      * with {@code step}.
438      * <p>
439      * Examples:
440      * <pre>
441      * <code>
442      * List.rangeBy(1, 3, 1)  // = List(1, 2)
443      * List.rangeBy(1, 4, 2)  // = List(1, 3)
444      * List.rangeBy(4, 1, -2) // = List(4, 2)
445      * List.rangeBy(4, 1, 2)  // = List()
446      * </code>
447      * </pre>
448      *
449      * @param from        the first number
450      * @param toExclusive the last number + 1
451      * @param step        the step
452      * @return a range of long values as specified or the empty range if<br>
453      * {@code from >= toInclusive} and {@code step > 0} or<br>
454      * {@code from <= toInclusive} and {@code step < 0}
455      * @throws IllegalArgumentException if {@code step} is zero
456      */
457     static List<Integer> rangeBy(int from, int toExclusive, int step) {
458         return ofAll(Iterator.rangeBy(from, toExclusive, step));
459     }
460 
461     /**
462      * Creates a List of long numbers starting from {@code from}, extending to {@code toExclusive - 1}.
463      * <p>
464      * Examples:
465      * <pre>
466      * <code>
467      * List.range(0L, 0L)  // = List()
468      * List.range(2L, 0L)  // = List()
469      * List.range(-2L, 2L) // = List(-2L, -1L, 0L, 1L)
470      * </code>
471      * </pre>
472      *
473      * @param from        the first number
474      * @param toExclusive the last number + 1
475      * @return a range of long values as specified or the empty range if {@code from >= toExclusive}
476      */
477     static List<Long> range(long from, long toExclusive) {
478         return ofAll(Iterator.range(from, toExclusive));
479     }
480 
481     /**
482      * Creates a List of long numbers starting from {@code from}, extending to {@code toExclusive - 1},
483      * with {@code step}.
484      * <p>
485      * Examples:
486      * <pre>
487      * <code>
488      * List.rangeBy(1L, 3L, 1L)  // = List(1L, 2L)
489      * List.rangeBy(1L, 4L, 2L)  // = List(1L, 3L)
490      * List.rangeBy(4L, 1L, -2L) // = List(4L, 2L)
491      * List.rangeBy(4L, 1L, 2L)  // = List()
492      * </code>
493      * </pre>
494      *
495      * @param from        the first number
496      * @param toExclusive the last number + 1
497      * @param step        the step
498      * @return a range of long values as specified or the empty range if<br>
499      * {@code from >= toInclusive} and {@code step > 0} or<br>
500      * {@code from <= toInclusive} and {@code step < 0}
501      * @throws IllegalArgumentException if {@code step} is zero
502      */
503     static List<Long> rangeBy(long from, long toExclusive, long step) {
504         return ofAll(Iterator.rangeBy(from, toExclusive, step));
505     }
506 
507     static List<Character> rangeClosed(char from, char toInclusive) {
508         return ofAll(Iterator.rangeClosed(from, toInclusive));
509     }
510 
511     static List<Character> rangeClosedBy(char from, char toInclusive, int step) {
512         return ofAll(Iterator.rangeClosedBy(from, toInclusive, step));
513     }
514 
515     @GwtIncompatible
516     static List<Double> rangeClosedBy(double from, double toInclusive, double step) {
517         return ofAll(Iterator.rangeClosedBy(from, toInclusive, step));
518     }
519 
520     /**
521      * Creates a List of int numbers starting from {@code from}, extending to {@code toInclusive}.
522      * <p>
523      * Examples:
524      * <pre>
525      * <code>
526      * List.rangeClosed(0, 0)  // = List(0)
527      * List.rangeClosed(2, 0)  // = List()
528      * List.rangeClosed(-2, 2) // = List(-2, -1, 0, 1, 2)
529      * </code>
530      * </pre>
531      *
532      * @param from        the first number
533      * @param toInclusive the last number
534      * @return a range of int values as specified or the empty range if {@code from > toInclusive}
535      */
536     static List<Integer> rangeClosed(int from, int toInclusive) {
537         return ofAll(Iterator.rangeClosed(from, toInclusive));
538     }
539 
540     /**
541      * Creates a List of int numbers starting from {@code from}, extending to {@code toInclusive},
542      * with {@code step}.
543      * <p>
544      * Examples:
545      * <pre>
546      * <code>
547      * List.rangeClosedBy(1, 3, 1)  // = List(1, 2, 3)
548      * List.rangeClosedBy(1, 4, 2)  // = List(1, 3)
549      * List.rangeClosedBy(4, 1, -2) // = List(4, 2)
550      * List.rangeClosedBy(4, 1, 2)  // = List()
551      * </code>
552      * </pre>
553      *
554      * @param from        the first number
555      * @param toInclusive the last number
556      * @param step        the step
557      * @return a range of int values as specified or the empty range if<br>
558      * {@code from > toInclusive} and {@code step > 0} or<br>
559      * {@code from < toInclusive} and {@code step < 0}
560      * @throws IllegalArgumentException if {@code step} is zero
561      */
562     static List<Integer> rangeClosedBy(int from, int toInclusive, int step) {
563         return ofAll(Iterator.rangeClosedBy(from, toInclusive, step));
564     }
565 
566     /**
567      * Creates a List of long numbers starting from {@code from}, extending to {@code toInclusive}.
568      * <p>
569      * Examples:
570      * <pre>
571      * <code>
572      * List.rangeClosed(0L, 0L)  // = List(0L)
573      * List.rangeClosed(2L, 0L)  // = List()
574      * List.rangeClosed(-2L, 2L) // = List(-2L, -1L, 0L, 1L, 2L)
575      * </code>
576      * </pre>
577      *
578      * @param from        the first number
579      * @param toInclusive the last number
580      * @return a range of long values as specified or the empty range if {@code from > toInclusive}
581      */
582     static List<Long> rangeClosed(long from, long toInclusive) {
583         return ofAll(Iterator.rangeClosed(from, toInclusive));
584     }
585 
586     /**
587      * Creates a List of long numbers starting from {@code from}, extending to {@code toInclusive},
588      * with {@code step}.
589      * <p>
590      * Examples:
591      * <pre>
592      * <code>
593      * List.rangeClosedBy(1L, 3L, 1L)  // = List(1L, 2L, 3L)
594      * List.rangeClosedBy(1L, 4L, 2L)  // = List(1L, 3L)
595      * List.rangeClosedBy(4L, 1L, -2L) // = List(4L, 2L)
596      * List.rangeClosedBy(4L, 1L, 2L)  // = List()
597      * </code>
598      * </pre>
599      *
600      * @param from        the first number
601      * @param toInclusive the last number
602      * @param step        the step
603      * @return a range of int values as specified or the empty range if<br>
604      * {@code from > toInclusive} and {@code step > 0} or<br>
605      * {@code from < toInclusive} and {@code step < 0}
606      * @throws IllegalArgumentException if {@code step} is zero
607      */
608     static List<Long> rangeClosedBy(long from, long toInclusive, long step) {
609         return ofAll(Iterator.rangeClosedBy(from, toInclusive, step));
610     }
611 
612     /**
613      * Transposes the rows and columns of a {@link List} matrix.
614      *
615      * @param <T> matrix element type
616      * @param matrix to be transposed.
617      * @return a transposed {@link List} matrix.
618      * @throws IllegalArgumentException if the row lengths of {@code matrix} differ.
619      * <p>
620      * ex: {@code
621      * List.transpose(List(List(1,2,3), List(4,5,6))) → List(List(1,4), List(2,5), List(3,6))
622      * }
623      */
624     static <T> List<List<T>> transpose(List<List<T>> matrix) {
625         return Collections.transpose(matrix, List::ofAll, List::of);
626     }
627 
628     /**
629      * Creates a list from a seed value and a function.
630      * The function takes the seed at first.
631      * The function should return {@code None} when it's
632      * done generating the list, otherwise {@code Some} {@code Tuple}
633      * of the element for the next call and the value to add to the
634      * resulting list.
635      * <p>
636      * Example:
637      * <pre>
638      * <code>
639      * List.unfoldRight(10, x -&gt; x == 0
640      *             ? Option.none()
641      *             : Option.of(new Tuple2&lt;&gt;(x, x-1)));
642      * // List(10, 9, 8, 7, 6, 5, 4, 3, 2, 1))
643      * </code>
644      * </pre>
645      *
646      * @param <T>  type of seeds
647      * @param <U>  type of unfolded values
648      * @param seed the start value for the iteration
649      * @param f    the function to get the next step of the iteration
650      * @return a list with the values built up by the iteration
651      * @throws NullPointerException if {@code f} is null
652      */
653     static <T, U> List<U> unfoldRight(T seed, Function<? super T, Option<Tuple2<? extends U, ? extends T>>> f) {
654         return Iterator.unfoldRight(seed, f).toList();
655     }
656 
657     /**
658      * Creates a list from a seed value and a function.
659      * The function takes the seed at first.
660      * The function should return {@code None} when it's
661      * done generating the list, otherwise {@code Some} {@code Tuple}
662      * of the value to add to the resulting list and
663      * the element for the next call.
664      * <p>
665      * Example:
666      * <pre>
667      * <code>
668      * List.unfoldLeft(10, x -&gt; x == 0
669      *             ? Option.none()
670      *             : Option.of(new Tuple2&lt;&gt;(x-1, x)));
671      * // List(1, 2, 3, 4, 5, 6, 7, 8, 9, 10))
672      * </code>
673      * </pre>
674      *
675      * @param <T>  type of seeds
676      * @param <U>  type of unfolded values
677      * @param seed the start value for the iteration
678      * @param f    the function to get the next step of the iteration
679      * @return a list with the values built up by the iteration
680      * @throws NullPointerException if {@code f} is null
681      */
682     static <T, U> List<U> unfoldLeft(T seed, Function<? super T, Option<Tuple2<? extends T, ? extends U>>> f) {
683         return Iterator.unfoldLeft(seed, f).toList();
684     }
685 
686     /**
687      * Creates a list from a seed value and a function.
688      * The function takes the seed at first.
689      * The function should return {@code None} when it's
690      * done generating the list, otherwise {@code Some} {@code Tuple}
691      * of the value to add to the resulting list and
692      * the element for the next call.
693      * <p>
694      * Example:
695      * <pre>
696      * <code>
697      * List.unfold(10, x -&gt; x == 0
698      *             ? Option.none()
699      *             : Option.of(new Tuple2&lt;&gt;(x-1, x)));
700      * // List(1, 2, 3, 4, 5, 6, 7, 8, 9, 10))
701      * </code>
702      * </pre>
703      *
704      * @param <T>  type of seeds and unfolded values
705      * @param seed the start value for the iteration
706      * @param f    the function to get the next step of the iteration
707      * @return a list with the values built up by the iteration
708      * @throws NullPointerException if {@code f} is null
709      */
710     static <T> List<T> unfold(T seed, Function<? super T, Option<Tuple2<? extends T, ? extends T>>> f) {
711         return Iterator.unfold(seed, f).toList();
712     }
713 
714     @Override
715     default List<T> append(T element) {
716         return foldRight(of(element), (x, xs) -> xs.prepend(x));
717     }
718 
719     @Override
720     default List<T> appendAll(Iterable<? extends T> elements) {
721         Objects.requireNonNull(elements, "elements is null");
722         return List.<T> ofAll(elements).prependAll(this);
723     }
724 
725     @Override
726     default java.util.List<T> asJava() {
727         return JavaConverters.asJava(this, IMMUTABLE);
728     }
729 
730     @Override
731     default List<T> asJava(Consumer<? super java.util.List<T>> action) {
732         return Collections.asJava(this, action, IMMUTABLE);
733     }
734 
735     @Override
736     default java.util.List<T> asJavaMutable() {
737         return JavaConverters.asJava(this, MUTABLE);
738     }
739 
740     @Override
741     default List<T> asJavaMutable(Consumer<? super java.util.List<T>> action) {
742         return Collections.asJava(this, action, MUTABLE);
743     }
744 
745     @Override
746     default <R> List<R> collect(PartialFunction<? super T, ? extends R> partialFunction) {
747         return ofAll(iterator().<R> collect(partialFunction));
748     }
749 
750     @Override
751     default List<List<T>> combinations() {
752         return rangeClosed(0, length()).map(this::combinations).flatMap(Function.identity());
753     }
754 
755     @Override
756     default List<List<T>> combinations(int k) {
757         return Combinations.apply(this, Math.max(k, 0));
758     }
759 
760     @Override
761     default Iterator<List<T>> crossProduct(int power) {
762         return Collections.crossProduct(empty(), this, power);
763     }
764 
765     @Override
766     default List<T> distinct() {
767         return distinctBy(Function.identity());
768     }
769 
770     @Override
771     default List<T> distinctBy(Comparator<? super T> comparator) {
772         Objects.requireNonNull(comparator, "comparator is null");
773         final java.util.Set<T> seen = new java.util.TreeSet<>(comparator);
774         return filter(seen::add);
775     }
776 
777     @Override
778     default <U> List<T> distinctBy(Function<? super T, ? extends U> keyExtractor) {
779         Objects.requireNonNull(keyExtractor, "keyExtractor is null");
780         final java.util.Set<U> seen = new java.util.HashSet<>();
781         return filter(t -> seen.add(keyExtractor.apply(t)));
782     }
783 
784     @Override
785     default List<T> drop(int n) {
786         if (n <= 0) {
787             return this;
788         }
789         if (n >= size()) {
790             return empty();
791         }
792         List<T> list = this;
793         for (long i = n; i > 0 && !list.isEmpty(); i--) {
794             list = list.tail();
795         }
796         return list;
797     }
798 
799     @Override
800     default List<T> dropUntil(Predicate<? super T> predicate) {
801         return Collections.dropUntil(this, predicate);
802     }
803 
804     @Override
805     default List<T> dropWhile(Predicate<? super T> predicate) {
806         Objects.requireNonNull(predicate, "predicate is null");
807         return dropUntil(predicate.negate());
808     }
809 
810     @Override
811     default List<T> dropRight(int n) {
812         if (n <= 0) {
813             return this;
814         }
815         if (n >= length()) {
816             return empty();
817         }
818         return ofAll(iterator().dropRight(n));
819     }
820 
821     @Override
822     default List<T> dropRightUntil(Predicate<? super T> predicate) {
823         return Collections.dropUntil(reverse(), predicate).reverse();
824     }
825 
826     @Override
827     default List<T> dropRightWhile(Predicate<? super T> predicate) {
828         Objects.requireNonNull(predicate, "predicate is null");
829         return dropRightUntil(predicate.negate());
830     }
831 
832     @Override
833     default List<T> filter(Predicate<? super T> predicate) {
834         Objects.requireNonNull(predicate, "predicate is null");
835         if (isEmpty()) {
836             return this;
837         } else {
838             final List<T> filtered = foldLeft(empty(), (xs, x) -> predicate.test(x) ? xs.prepend(x) : xs);
839             if (filtered.isEmpty()) {
840                 return empty();
841             } else if (filtered.length() == length()) {
842                 return this;
843             } else {
844                 return filtered.reverse();
845             }
846         }
847     }
848 
849     @Override
850     default <U> List<U> flatMap(Function<? super T, ? extends Iterable<? extends U>> mapper) {
851         Objects.requireNonNull(mapper, "mapper is null");
852         List<U> list = empty();
853         for (T t : this) {
854             for (U u : mapper.apply(t)) {
855                 list = list.prepend(u);
856             }
857         }
858         return list.reverse();
859     }
860 
861     @Override
862     default T get(int index) {
863         if (isEmpty()) {
864             throw new IndexOutOfBoundsException("get(" + index + ") on Nil");
865         }
866         if (index < 0) {
867             throw new IndexOutOfBoundsException("get(" + index + ")");
868         }
869         List<T> list = this;
870         for (int i = index - 1; i >= 0; i--) {
871             list = list.tail();
872             if (list.isEmpty()) {
873                 throw new IndexOutOfBoundsException("get(" + index + ") on List of length " + (index - i));
874             }
875         }
876         return list.head();
877     }
878 
879     @Override
880     default <C> Map<C, List<T>> groupBy(Function<? super T, ? extends C> classifier) {
881         return Collections.groupBy(this, classifier, List::ofAll);
882     }
883 
884     @Override
885     default Iterator<List<T>> grouped(int size) {
886         return sliding(size, size);
887     }
888 
889     @Override
890     default boolean hasDefiniteSize() {
891         return true;
892     }
893 
894     @Override
895     default int indexOf(T element, int from) {
896         int index = 0;
897         for (List<T> list = this; !list.isEmpty(); list = list.tail(), index++) {
898             if (index >= from && Objects.equals(list.head(), element)) {
899                 return index;
900             }
901         }
902         return -1;
903     }
904 
905     @Override
906     default List<T> init() {
907         if (isEmpty()) {
908             throw new UnsupportedOperationException("init of empty list");
909         } else {
910             return dropRight(1);
911         }
912     }
913 
914     @Override
915     default Option<List<T>> initOption() {
916         return isEmpty() ? Option.none() : Option.some(init());
917     }
918 
919     @Override
920     int length();
921 
922     @Override
923     default List<T> insert(int index, T element) {
924         if (index < 0) {
925             throw new IndexOutOfBoundsException("insert(" + index + ", e)");
926         }
927         List<T> preceding = Nil.instance();
928         List<T> tail = this;
929         for (int i = index; i > 0; i--, tail = tail.tail()) {
930             if (tail.isEmpty()) {
931                 throw new IndexOutOfBoundsException("insert(" + index + ", e) on List of length " + length());
932             }
933             preceding = preceding.prepend(tail.head());
934         }
935         List<T> result = tail.prepend(element);
936         for (T next : preceding) {
937             result = result.prepend(next);
938         }
939         return result;
940     }
941 
942     @Override
943     default List<T> insertAll(int index, Iterable<? extends T> elements) {
944         Objects.requireNonNull(elements, "elements is null");
945         if (index < 0) {
946             throw new IndexOutOfBoundsException("insertAll(" + index + ", elements)");
947         }
948         List<T> preceding = Nil.instance();
949         List<T> tail = this;
950         for (int i = index; i > 0; i--, tail = tail.tail()) {
951             if (tail.isEmpty()) {
952                 throw new IndexOutOfBoundsException("insertAll(" + index + ", elements) on List of length " + length());
953             }
954             preceding = preceding.prepend(tail.head());
955         }
956         List<T> result = tail.prependAll(elements);
957         for (T next : preceding) {
958             result = result.prepend(next);
959         }
960         return result;
961     }
962 
963     @Override
964     default List<T> intersperse(T element) {
965         return ofAll(iterator().intersperse(element));
966     }
967 
968     @Override
969     default boolean isTraversableAgain() {
970         return true;
971     }
972 
973     @Override
974     default int lastIndexOf(T element, int end) {
975         int result = -1, index = 0;
976         for (List<T> list = this; index <= end && !list.isEmpty(); list = list.tail(), index++) {
977             if (Objects.equals(list.head(), element)) {
978                 result = index;
979             }
980         }
981         return result;
982     }
983 
984     @Override
985     default <U> List<U> map(Function<? super T, ? extends U> mapper) {
986         Objects.requireNonNull(mapper, "mapper is null");
987         List<U> list = empty();
988         for (T t : this) {
989             list = list.prepend(mapper.apply(t));
990         }
991         return list.reverse();
992     }
993 
994     @Override
995     default List<T> orElse(Iterable<? extends T> other) {
996         return isEmpty() ? ofAll(other) : this;
997     }
998 
999     @Override
1000     default List<T> orElse(Supplier<? extends Iterable<? extends T>> supplier) {
1001         return isEmpty() ? ofAll(supplier.get()) : this;
1002     }
1003 
1004     @Override
1005     default List<T> padTo(int length, T element) {
1006         final int actualLength = length();
1007         if (length <= actualLength) {
1008             return this;
1009         } else {
1010             return appendAll(Iterator.continually(element).take(length - actualLength));
1011         }
1012     }
1013 
1014     @Override
1015     default List<T> leftPadTo(int length, T element) {
1016         final int actualLength = length();
1017         if (length <= actualLength) {
1018             return this;
1019         } else {
1020             return prependAll(Iterator.continually(element).take(length - actualLength));
1021         }
1022     }
1023 
1024     @Override
1025     default List<T> patch(int from, Iterable<? extends T> that, int replaced) {
1026         from = from < 0 ? 0 : from;
1027         replaced = replaced < 0 ? 0 : replaced;
1028         List<T> result = take(from).appendAll(that);
1029         from += replaced;
1030         result = result.appendAll(drop(from));
1031         return result;
1032     }
1033 
1034     @Override
1035     default Tuple2<List<T>, List<T>> partition(Predicate<? super T> predicate) {
1036         Objects.requireNonNull(predicate, "predicate is null");
1037         List<T> left = empty(), right = empty();
1038         for (T t : this) {
1039             if (predicate.test(t)) {
1040                 left = left.prepend(t);
1041             } else {
1042                 right = right.prepend(t);
1043             }
1044         }
1045         return Tuple.of(left.reverse(), right.reverse());
1046     }
1047 
1048     /**
1049      * Returns the head element without modifying the List.
1050      *
1051      * @return the first element
1052      * @throws java.util.NoSuchElementException if this List is empty
1053      */
1054     default T peek() {
1055         if (isEmpty()) {
1056             throw new NoSuchElementException("peek of empty list");
1057         }
1058         return head();
1059     }
1060 
1061     /**
1062      * Returns the head element without modifying the List.
1063      *
1064      * @return {@code None} if this List is empty, otherwise a {@code Some} containing the head element
1065      */
1066     default Option<T> peekOption() {
1067         return isEmpty() ? Option.none() : Option.some(head());
1068     }
1069 
1070     /**
1071      * Performs an action on the head element of this {@code List}.
1072      *
1073      * @param action A {@code Consumer}
1074      * @return this {@code List}
1075      */
1076     @Override
1077     default List<T> peek(Consumer<? super T> action) {
1078         Objects.requireNonNull(action, "action is null");
1079         if (!isEmpty()) {
1080             action.accept(head());
1081         }
1082         return this;
1083     }
1084 
1085     @Override
1086     default List<List<T>> permutations() {
1087         if (isEmpty()) {
1088             return Nil.instance();
1089         } else {
1090             final List<T> tail = tail();
1091             if (tail.isEmpty()) {
1092                 return of(this);
1093             } else {
1094                 final List<List<T>> zero = Nil.instance();
1095                 return distinct().foldLeft(zero, (xs, x) -> {
1096                     final Function<List<T>, List<T>> prepend = l -> l.prepend(x);
1097                     return xs.appendAll(remove(x).permutations().map(prepend));
1098                 });
1099             }
1100         }
1101     }
1102 
1103     /**
1104      * Removes the head element from this List.
1105      *
1106      * @return the elements of this List without the head element
1107      * @throws java.util.NoSuchElementException if this List is empty
1108      */
1109     default List<T> pop() {
1110         if (isEmpty()) {
1111             throw new NoSuchElementException("pop of empty list");
1112         }
1113         return tail();
1114     }
1115 
1116     /**
1117      * Removes the head element from this List.
1118      *
1119      * @return {@code None} if this List is empty, otherwise a {@code Some} containing the elements of this List without the head element
1120      */
1121     default Option<List<T>> popOption() {
1122         return isEmpty() ? Option.none() : Option.some(pop());
1123     }
1124 
1125     /**
1126      * Removes the head element from this List.
1127      *
1128      * @return a tuple containing the head element and the remaining elements of this List
1129      * @throws java.util.NoSuchElementException if this List is empty
1130      */
1131     default Tuple2<T, List<T>> pop2() {
1132         if (isEmpty()) {
1133             throw new NoSuchElementException("pop2 of empty list");
1134         }
1135         return Tuple.of(head(), tail());
1136     }
1137 
1138     /**
1139      * Removes the head element from this List.
1140      *
1141      * @return {@code None} if this List is empty, otherwise {@code Some} {@code Tuple} containing the head element and the remaining elements of this List
1142      */
1143     default Option<Tuple2<T, List<T>>> pop2Option() {
1144         return isEmpty() ? Option.none() : Option.some(Tuple.of(head(), pop()));
1145     }
1146 
1147     @Override
1148     default List<T> prepend(T element) {
1149         return new Cons<>(element, this);
1150     }
1151 
1152     @Override
1153     default List<T> prependAll(Iterable<? extends T> elements) {
1154         Objects.requireNonNull(elements, "elements is null");
1155         return isEmpty() ? ofAll(elements) : ofAll(elements).reverse().foldLeft(this, List::prepend);
1156     }
1157 
1158     /**
1159      * Pushes a new element on top of this List.
1160      *
1161      * @param element The new element
1162      * @return a new {@code List} instance, containing the new element on top of this List
1163      */
1164     default List<T> push(T element) {
1165         return new Cons<>(element, this);
1166     }
1167 
1168     /**
1169      * Pushes the given elements on top of this List. A List has LIFO order, i.e. the last of the given elements is
1170      * the first which will be retrieved.
1171      *
1172      * @param elements Elements, may be empty
1173      * @return a new {@code List} instance, containing the new elements on top of this List
1174      * @throws NullPointerException if elements is null
1175      */
1176     @SuppressWarnings("unchecked")
1177     default List<T> push(T... elements) {
1178         Objects.requireNonNull(elements, "elements is null");
1179         List<T> result = this;
1180         for (T element : elements) {
1181             result = result.prepend(element);
1182         }
1183         return result;
1184     }
1185 
1186     /**
1187      * Pushes the given elements on top of this List. A List has LIFO order, i.e. the last of the given elements is
1188      * the first which will be retrieved.
1189      *
1190      * @param elements An Iterable of elements, may be empty
1191      * @return a new {@code List} instance, containing the new elements on top of this List
1192      * @throws NullPointerException if elements is null
1193      */
1194     default List<T> pushAll(Iterable<T> elements) {
1195         Objects.requireNonNull(elements, "elements is null");
1196         List<T> result = this;
1197         for (T element : elements) {
1198             result = result.prepend(element);
1199         }
1200         return result;
1201     }
1202 
1203     @Override
1204     default List<T> remove(T element) {
1205         final Deque<T> preceding = new ArrayDeque<>(size());
1206         List<T> result = this;
1207         boolean found = false;
1208         while (!found && !result.isEmpty()) {
1209             final T head = result.head();
1210             if (Objects.equals(head, element)) {
1211                 found = true;
1212             } else {
1213                 preceding.addFirst(head);
1214             }
1215             result = result.tail();
1216         }
1217         if (!found) {
1218             return this;
1219         }
1220         for (T next : preceding) {
1221             result = result.prepend(next);
1222         }
1223         return result;
1224     }
1225 
1226     @Override
1227     default List<T> removeFirst(Predicate<T> predicate) {
1228         Objects.requireNonNull(predicate, "predicate is null");
1229         List<T> init = empty();
1230         List<T> tail = this;
1231         while (!tail.isEmpty() && !predicate.test(tail.head())) {
1232             init = init.prepend(tail.head());
1233             tail = tail.tail();
1234         }
1235         if (tail.isEmpty()) {
1236             return this;
1237         } else {
1238             return init.foldLeft(tail.tail(), List::prepend);
1239         }
1240     }
1241 
1242     @Override
1243     default List<T> removeLast(Predicate<T> predicate) {
1244         Objects.requireNonNull(predicate, "predicate is null");
1245         final List<T> removedAndReversed = reverse().removeFirst(predicate);
1246         return removedAndReversed.length() == length() ? this : removedAndReversed.reverse();
1247     }
1248 
1249     @Override
1250     default List<T> removeAt(int index) {
1251         if (index < 0) {
1252             throw new IndexOutOfBoundsException("removeAt(" + index + ")");
1253         }
1254         if (isEmpty()) {
1255             throw new IndexOutOfBoundsException("removeAt(" + index + ") on Nil");
1256         }
1257         List<T> init = Nil.instance();
1258         List<T> tail = this;
1259         while (index > 0 && !tail.isEmpty()) {
1260             init = init.prepend(tail.head());
1261             tail = tail.tail();
1262             index--;
1263         }
1264         if (index > 0) {
1265             throw new IndexOutOfBoundsException("removeAt() on Nil");
1266         }
1267         return init.reverse().appendAll(tail.tail());
1268     }
1269 
1270     @Override
1271     default List<T> removeAll(T element) {
1272         return Collections.removeAll(this, element);
1273     }
1274 
1275     @Override
1276     default List<T> removeAll(Iterable<? extends T> elements) {
1277         return Collections.removeAll(this, elements);
1278     }
1279 
1280     @Override
1281     default List<T> removeAll(Predicate<? super T> predicate) {
1282         return Collections.removeAll(this, predicate);
1283     }
1284 
1285     @Override
1286     default List<T> replace(T currentElement, T newElement) {
1287         List<T> preceding = Nil.instance();
1288         List<T> tail = this;
1289         while (!tail.isEmpty() && !Objects.equals(tail.head(), currentElement)) {
1290             preceding = preceding.prepend(tail.head());
1291             tail = tail.tail();
1292         }
1293         if (tail.isEmpty()) {
1294             return this;
1295         }
1296         // skip the current head element because it is replaced
1297         List<T> result = tail.tail().prepend(newElement);
1298         for (T next : preceding) {
1299             result = result.prepend(next);
1300         }
1301         return result;
1302     }
1303 
1304     @Override
1305     default List<T> replaceAll(T currentElement, T newElement) {
1306         List<T> result = Nil.instance();
1307         boolean changed = false;
1308         for (List<T> list = this; !list.isEmpty(); list = list.tail()) {
1309             final T head = list.head();
1310             if (Objects.equals(head, currentElement)) {
1311                 result = result.prepend(newElement);
1312                 changed = true;
1313             } else {
1314                 result = result.prepend(head);
1315             }
1316         }
1317         return changed ? result.reverse() : this;
1318     }
1319 
1320     @Override
1321     default List<T> retainAll(Iterable<? extends T> elements) {
1322         return Collections.retainAll(this, elements);
1323     }
1324 
1325     @Override
1326     default List<T> reverse() {
1327         return (length() <= 1) ? this : foldLeft(empty(), List::prepend);
1328     }
1329 
1330     @Override
1331     default List<T> scan(T zero, BiFunction<? super T, ? super T, ? extends T> operation) {
1332         return scanLeft(zero, operation);
1333     }
1334 
1335     @Override
1336     default <U> List<U> scanLeft(U zero, BiFunction<? super U, ? super T, ? extends U> operation) {
1337         return Collections.scanLeft(this, zero, operation, Iterator::toList);
1338     }
1339 
1340     @Override
1341     default <U> List<U> scanRight(U zero, BiFunction<? super T, ? super U, ? extends U> operation) {
1342         return Collections.scanRight(this, zero, operation, Iterator::toList);
1343     }
1344 
1345     @Override
1346     default List<T> shuffle() {
1347         return Collections.shuffle(this, List::ofAll);
1348     }
1349 
1350     @Override
1351     default List<T> slice(int beginIndex, int endIndex) {
1352         if (beginIndex >= endIndex || beginIndex >= length() || isEmpty()) {
1353             return empty();
1354         } else {
1355             List<T> result = Nil.instance();
1356             List<T> list = this;
1357             final long lowerBound = Math.max(beginIndex, 0);
1358             final long upperBound = Math.min(endIndex, length());
1359             for (int i = 0; i < upperBound; i++) {
1360                 if (i >= lowerBound) {
1361                     result = result.prepend(list.head());
1362                 }
1363                 list = list.tail();
1364             }
1365             return result.reverse();
1366         }
1367     }
1368 
1369     @Override
1370     default Iterator<List<T>> slideBy(Function<? super T, ?> classifier) {
1371         return iterator().slideBy(classifier).map(List::ofAll);
1372     }
1373 
1374     @Override
1375     default Iterator<List<T>> sliding(int size) {
1376         return sliding(size, 1);
1377     }
1378 
1379     @Override
1380     default Iterator<List<T>> sliding(int size, int step) {
1381         return iterator().sliding(size, step).map(List::ofAll);
1382     }
1383 
1384     @Override
1385     default List<T> sorted() {
1386         return isEmpty() ? this : toJavaStream().sorted().collect(collector());
1387     }
1388 
1389     @Override
1390     default List<T> sorted(Comparator<? super T> comparator) {
1391         Objects.requireNonNull(comparator, "comparator is null");
1392         return isEmpty() ? this : toJavaStream().sorted(comparator).collect(collector());
1393     }
1394 
1395     @Override
1396     default <U extends Comparable<? super U>> List<T> sortBy(Function<? super T, ? extends U> mapper) {
1397         return sortBy(U::compareTo, mapper);
1398     }
1399 
1400     @Override
1401     default <U> List<T> sortBy(Comparator<? super U> comparator, Function<? super T, ? extends U> mapper) {
1402         final Function<? super T, ? extends U> domain = Function1.of(mapper::apply).memoized();
1403         return toJavaStream()
1404                 .sorted((e1, e2) -> comparator.compare(domain.apply(e1), domain.apply(e2)))
1405                 .collect(collector());
1406     }
1407 
1408     @Override
1409     default Tuple2<List<T>, List<T>> span(Predicate<? super T> predicate) {
1410         Objects.requireNonNull(predicate, "predicate is null");
1411         final Tuple2<Iterator<T>, Iterator<T>> itt = iterator().span(predicate);
1412         return Tuple.of(ofAll(itt._1), ofAll(itt._2));
1413     }
1414 
1415     @Override
1416     default Tuple2<List<T>, List<T>> splitAt(int n) {
1417         if (isEmpty()) {
1418             return Tuple.of(empty(), empty());
1419         } else {
1420             List<T> init = Nil.instance();
1421             List<T> tail = this;
1422             while (n > 0 && !tail.isEmpty()) {
1423                 init = init.prepend(tail.head());
1424                 tail = tail.tail();
1425                 n--;
1426             }
1427             return Tuple.of(init.reverse(), tail);
1428         }
1429     }
1430 
1431     @Override
1432     default Tuple2<List<T>, List<T>> splitAt(Predicate<? super T> predicate) {
1433         if (isEmpty()) {
1434             return Tuple.of(empty(), empty());
1435         } else {
1436             final Tuple2<List<T>, List<T>> t = SplitAt.splitByPredicateReversed(this, predicate);
1437             if (t._2.isEmpty()) {
1438                 return Tuple.of(this, empty());
1439             } else {
1440                 return Tuple.of(t._1.reverse(), t._2);
1441             }
1442         }
1443     }
1444 
1445     @Override
1446     default Tuple2<List<T>, List<T>> splitAtInclusive(Predicate<? super T> predicate) {
1447         if (isEmpty()) {
1448             return Tuple.of(empty(), empty());
1449         } else {
1450             final Tuple2<List<T>, List<T>> t = SplitAt.splitByPredicateReversed(this, predicate);
1451             if (t._2.isEmpty() || t._2.tail().isEmpty()) {
1452                 return Tuple.of(this, empty());
1453             } else {
1454                 return Tuple.of(t._1.prepend(t._2.head()).reverse(), t._2.tail());
1455             }
1456         }
1457     }
1458 
1459     @Override
1460     default String stringPrefix() {
1461         return "List";
1462     }
1463 
1464     @Override
1465     default List<T> subSequence(int beginIndex) {
1466         if (beginIndex < 0 || beginIndex > length()) {
1467             throw new IndexOutOfBoundsException("subSequence(" + beginIndex + ")");
1468         } else {
1469             return drop(beginIndex);
1470         }
1471     }
1472 
1473     @Override
1474     default List<T> subSequence(int beginIndex, int endIndex) {
1475         Collections.subSequenceRangeCheck(beginIndex, endIndex, length());
1476         if (beginIndex == endIndex) {
1477             return empty();
1478         } else if (beginIndex == 0 && endIndex == length()) {
1479             return this;
1480         } else {
1481             List<T> result = Nil.instance();
1482             List<T> list = this;
1483             for (int i = 0; i < endIndex; i++, list = list.tail()) {
1484                 if (i >= beginIndex) {
1485                     result = result.prepend(list.head());
1486                 }
1487             }
1488             return result.reverse();
1489         }
1490     }
1491 
1492     @Override
1493     List<T> tail();
1494 
1495     @Override
1496     default Option<List<T>> tailOption() {
1497         return isEmpty() ? Option.none() : Option.some(tail());
1498     }
1499 
1500     @Override
1501     default List<T> take(int n) {
1502         if (n <= 0) {
1503             return empty();
1504         }
1505         if (n >= length()) {
1506             return this;
1507         }
1508         List<T> result = Nil.instance();
1509         List<T> list = this;
1510         for (int i = 0; i < n; i++, list = list.tail()) {
1511             result = result.prepend(list.head());
1512         }
1513         return result.reverse();
1514     }
1515 
1516     @Override
1517     default List<T> takeRight(int n) {
1518         if (n <= 0) {
1519             return empty();
1520         }
1521         if (n >= length()) {
1522             return this;
1523         }
1524         return reverse().take(n).reverse();
1525     }
1526 
1527     @Override
1528     default List<T> takeUntil(Predicate<? super T> predicate) {
1529         Objects.requireNonNull(predicate, "predicate is null");
1530         return takeWhile(predicate.negate());
1531     }
1532 
1533     @Override
1534     default List<T> takeWhile(Predicate<? super T> predicate) {
1535         Objects.requireNonNull(predicate, "predicate is null");
1536         List<T> result = Nil.instance();
1537         for (List<T> list = this; !list.isEmpty() && predicate.test(list.head()); list = list.tail()) {
1538             result = result.prepend(list.head());
1539         }
1540         return result.length() == length() ? this : result.reverse();
1541     }
1542 
1543     /**
1544      * Transforms this {@code List}.
1545      *
1546      * @param f   A transformation
1547      * @param <U> Type of transformation result
1548      * @return An instance of type {@code U}
1549      * @throws NullPointerException if {@code f} is null
1550      */
1551     default <U> U transform(Function<? super List<T>, ? extends U> f) {
1552         Objects.requireNonNull(f, "f is null");
1553         return f.apply(this);
1554     }
1555 
1556     @Override
1557     default <T1, T2> Tuple2<List<T1>, List<T2>> unzip(
1558             Function<? super T, Tuple2<? extends T1, ? extends T2>> unzipper) {
1559         Objects.requireNonNull(unzipper, "unzipper is null");
1560         List<T1> xs = Nil.instance();
1561         List<T2> ys = Nil.instance();
1562         for (T element : this) {
1563             final Tuple2<? extends T1, ? extends T2> t = unzipper.apply(element);
1564             xs = xs.prepend(t._1);
1565             ys = ys.prepend(t._2);
1566         }
1567         return Tuple.of(xs.reverse(), ys.reverse());
1568     }
1569 
1570     @Override
1571     default <T1, T2, T3> Tuple3<List<T1>, List<T2>, List<T3>> unzip3(
1572             Function<? super T, Tuple3<? extends T1, ? extends T2, ? extends T3>> unzipper) {
1573         Objects.requireNonNull(unzipper, "unzipper is null");
1574         List<T1> xs = Nil.instance();
1575         List<T2> ys = Nil.instance();
1576         List<T3> zs = Nil.instance();
1577         for (T element : this) {
1578             final Tuple3<? extends T1, ? extends T2, ? extends T3> t = unzipper.apply(element);
1579             xs = xs.prepend(t._1);
1580             ys = ys.prepend(t._2);
1581             zs = zs.prepend(t._3);
1582         }
1583         return Tuple.of(xs.reverse(), ys.reverse(), zs.reverse());
1584     }
1585 
1586     @Override
1587     default List<T> update(int index, T element) {
1588         if (isEmpty()) {
1589             throw new IndexOutOfBoundsException("update(" + index + ", e) on Nil");
1590         }
1591         if (index < 0) {
1592             throw new IndexOutOfBoundsException("update(" + index + ", e)");
1593         }
1594         List<T> preceding = Nil.instance();
1595         List<T> tail = this;
1596         for (int i = index; i > 0; i--, tail = tail.tail()) {
1597             if (tail.isEmpty()) {
1598                 throw new IndexOutOfBoundsException("update(" + index + ", e) on List of length " + length());
1599             }
1600             preceding = preceding.prepend(tail.head());
1601         }
1602         if (tail.isEmpty()) {
1603             throw new IndexOutOfBoundsException("update(" + index + ", e) on List of length " + length());
1604         }
1605         // skip the current head element because it is replaced
1606         List<T> result = tail.tail().prepend(element);
1607         for (T next : preceding) {
1608             result = result.prepend(next);
1609         }
1610         return result;
1611     }
1612 
1613     @Override
1614     default List<T> update(int index, Function<? super T, ? extends T> updater) {
1615         Objects.requireNonNull(updater, "updater is null");
1616         return update(index, updater.apply(get(index)));
1617     }
1618 
1619     @Override
1620     default <U> List<Tuple2<T, U>> zip(Iterable<? extends U> that) {
1621         return zipWith(that, Tuple::of);
1622     }
1623 
1624     @Override
1625     default <U, R> List<R> zipWith(Iterable<? extends U> that, BiFunction<? super T, ? super U, ? extends R> mapper) {
1626         Objects.requireNonNull(that, "that is null");
1627         Objects.requireNonNull(mapper, "mapper is null");
1628         return ofAll(iterator().zipWith(that, mapper));
1629     }
1630 
1631     @Override
1632     default <U> List<Tuple2<T, U>> zipAll(Iterable<? extends U> that, T thisElem, U thatElem) {
1633         Objects.requireNonNull(that, "that is null");
1634         return ofAll(iterator().zipAll(that, thisElem, thatElem));
1635     }
1636 
1637     @Override
1638     default List<Tuple2<T, Integer>> zipWithIndex() {
1639         return zipWithIndex(Tuple::of);
1640     }
1641 
1642     @Override
1643     default <U> List<U> zipWithIndex(BiFunction<? super T, ? super Integer, ? extends U> mapper) {
1644         Objects.requireNonNull(mapper, "mapper is null");
1645         return ofAll(iterator().zipWithIndex(mapper));
1646     }
1647 
1648     /**
1649      * Representation of the singleton empty {@code List}.
1650      *
1651      * @param <T> Component type of the List.
1652      */
1653     final class Nil<T> implements List<T>, Serializable {
1654 
1655         private static final long serialVersionUID = 1L;
1656 
1657         private static final Nil<?> INSTANCE = new Nil<>();
1658 
1659         // hidden
1660         private Nil() {
1661         }
1662 
1663         /**
1664          * Returns the singleton instance of the linked list.
1665          *
1666          * @param <T> Component type of the List
1667          * @return the singleton instance of the linked list.
1668          */
1669         @SuppressWarnings("unchecked")
1670         public static <T> Nil<T> instance() {
1671             return (Nil<T>) INSTANCE;
1672         }
1673 
1674         @Override
1675         public T head() {
1676             throw new NoSuchElementException("head of empty list");
1677         }
1678 
1679         @Override
1680         public int length() {
1681             return 0;
1682         }
1683 
1684         @Override
1685         public List<T> tail() {
1686             throw new UnsupportedOperationException("tail of empty list");
1687         }
1688 
1689         @Override
1690         public boolean isEmpty() {
1691             return true;
1692         }
1693 
1694         @Override
1695         public boolean equals(Object o) {
1696             return Collections.equals(this, o);
1697         }
1698 
1699         @Override
1700         public int hashCode() {
1701             return Collections.hashOrdered(this);
1702         }
1703 
1704         @Override
1705         public String toString() {
1706             return stringPrefix() + "()";
1707         }
1708 
1709         /**
1710          * Instance control for object serialization.
1711          *
1712          * @return The singleton instance of Nil.
1713          * @see java.io.Serializable
1714          */
1715         private Object readResolve() {
1716             return INSTANCE;
1717         }
1718     }
1719 
1720     /**
1721      * Non-empty {@code List}, consisting of a {@code head} and a {@code tail}.
1722      *
1723      * @param <T> Component type of the List.
1724      */
1725     // DEV NOTE: class declared final because of serialization proxy pattern (see Effective Java, 2nd ed., p. 315)
1726     final class Cons<T> implements List<T>, Serializable {
1727 
1728         private static final long serialVersionUID = 1L;
1729 
1730         private final T head;
1731         private final List<T> tail;
1732         private final int length;
1733 
1734         /**
1735          * Creates a List consisting of a head value and a trailing List.
1736          *
1737          * @param head The head
1738          * @param tail The tail
1739          */
1740         private Cons(T head, List<T> tail) {
1741             this.head = head;
1742             this.tail = tail;
1743             this.length = 1 + tail.length();
1744         }
1745 
1746         @Override
1747         public T head() {
1748             return head;
1749         }
1750 
1751         @Override
1752         public int length() {
1753             return length;
1754         }
1755 
1756         @Override
1757         public List<T> tail() {
1758             return tail;
1759         }
1760 
1761         @Override
1762         public boolean isEmpty() {
1763             return false;
1764         }
1765 
1766         @Override
1767         public boolean equals(Object o) {
1768             return Collections.equals(this, o);
1769         }
1770 
1771         @Override
1772         public int hashCode() {
1773             return Collections.hashOrdered(this);
1774         }
1775 
1776         @Override
1777         public String toString() {
1778             return mkString(stringPrefix() + "(", ", ", ")");
1779         }
1780 
1781         /**
1782          * {@code writeReplace} method for the serialization proxy pattern.
1783          * <p>
1784          * The presence of this method causes the serialization system to emit a SerializationProxy instance instead of
1785          * an instance of the enclosing class.
1786          *
1787          * @return A SerializationProxy for this enclosing class.
1788          */
1789         @GwtIncompatible("The Java serialization protocol is explicitly not supported")
1790         private Object writeReplace() {
1791             return new SerializationProxy<>(this);
1792         }
1793 
1794         /**
1795          * {@code readObject} method for the serialization proxy pattern.
1796          * <p>
1797          * Guarantees that the serialization system will never generate a serialized instance of the enclosing class.
1798          *
1799          * @param stream An object serialization stream.
1800          * @throws java.io.InvalidObjectException This method will throw with the message "Proxy required".
1801          */
1802         @GwtIncompatible("The Java serialization protocol is explicitly not supported")
1803         private void readObject(ObjectInputStream stream) throws InvalidObjectException {
1804             throw new InvalidObjectException("Proxy required");
1805         }
1806 
1807         /**
1808          * A serialization proxy which, in this context, is used to deserialize immutable, linked Lists with final
1809          * instance fields.
1810          *
1811          * @param <T> The component type of the underlying list.
1812          */
1813         // DEV NOTE: The serialization proxy pattern is not compatible with non-final, i.e. extendable,
1814         // classes. Also, it may not be compatible with circular object graphs.
1815         @GwtIncompatible("The Java serialization protocol is explicitly not supported")
1816         private static final class SerializationProxy<T> implements Serializable {
1817 
1818             private static final long serialVersionUID = 1L;
1819 
1820             // the instance to be serialized/deserialized
1821             private transient Cons<T> list;
1822 
1823             /**
1824              * Constructor for the case of serialization, called by {@link Cons#writeReplace()}.
1825              * <p/>
1826              * The constructor of a SerializationProxy takes an argument that concisely represents the logical state of
1827              * an instance of the enclosing class.
1828              *
1829              * @param list a Cons
1830              */
1831             SerializationProxy(Cons<T> list) {
1832                 this.list = list;
1833             }
1834 
1835             /**
1836              * Write an object to a serialization stream.
1837              *
1838              * @param s An object serialization stream.
1839              * @throws java.io.IOException If an error occurs writing to the stream.
1840              */
1841             private void writeObject(ObjectOutputStream s) throws IOException {
1842                 s.defaultWriteObject();
1843                 s.writeInt(list.length());
1844                 for (List<T> l = list; !l.isEmpty(); l = l.tail()) {
1845                     s.writeObject(l.head());
1846                 }
1847             }
1848 
1849             /**
1850              * Read an object from a deserialization stream.
1851              *
1852              * @param s An object deserialization stream.
1853              * @throws ClassNotFoundException If the object's class read from the stream cannot be found.
1854              * @throws InvalidObjectException If the stream contains no list elements.
1855              * @throws IOException            If an error occurs reading from the stream.
1856              */
1857             private void readObject(ObjectInputStream s) throws ClassNotFoundException, IOException {
1858                 s.defaultReadObject();
1859                 final int size = s.readInt();
1860                 if (size <= 0) {
1861                     throw new InvalidObjectException("No elements");
1862                 }
1863                 List<T> temp = Nil.instance();
1864                 for (int i = 0; i < size; i++) {
1865                     @SuppressWarnings("unchecked")
1866                     final T element = (T) s.readObject();
1867                     temp = temp.prepend(element);
1868                 }
1869                 list = (Cons<T>) temp.reverse();
1870             }
1871 
1872             /**
1873              * {@code readResolve} method for the serialization proxy pattern.
1874              * <p>
1875              * Returns a logically equivalent instance of the enclosing class. The presence of this method causes the
1876              * serialization system to translate the serialization proxy back into an instance of the enclosing class
1877              * upon deserialization.
1878              *
1879              * @return A deserialized instance of the enclosing class.
1880              */
1881             private Object readResolve() {
1882                 return list;
1883             }
1884         }
1885     }
1886 }
1887 
1888 interface ListModule {
1889 
1890     interface Combinations {
1891 
1892         static <T> List<List<T>> apply(List<T> elements, int k) {
1893             if (k == 0) {
1894                 return List.of(List.empty());
1895             } else {
1896                 return elements.zipWithIndex().flatMap(
1897                         t -> apply(elements.drop(t._2 + 1), (k - 1)).map(c -> c.prepend(t._1))
1898                 );
1899             }
1900         }
1901     }
1902 
1903     interface SplitAt {
1904 
1905         static <T> Tuple2<List<T>, List<T>> splitByPredicateReversed(List<T> source, Predicate<? super T> predicate) {
1906             Objects.requireNonNull(predicate, "predicate is null");
1907             List<T> init = Nil.instance();
1908             List<T> tail = source;
1909             while (!tail.isEmpty() && !predicate.test(tail.head())) {
1910                 init = init.prepend(tail.head());
1911                 tail = tail.tail();
1912             }
1913             return Tuple.of(init, tail);
1914         }
1915     }
1916 }